package com.zjhhsd.blackJack.util;

import com.zjhhsd.blackJack.model.Card;
import com.zjhhsd.blackJack.model.RoomInfo;
import com.zjhhsd.blackJack.model.UserInfo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class CardUtil {

    private static final ArrayList<Card> cardList = new ArrayList<>();

    public static ArrayList<String> roomLog = RoomUtil.roomLog;

    public static boolean needClear = false;

    private static int count = 0; //记张器

    private static int roomCount = 1; //对局计数器

    public synchronized static void initCardList(){
        cardList.clear();//清空之前的元素
        for (int i = 1; i <= 54; i++){
            Card card = new Card();
            card.setId(i);
            card.setUrl(String.valueOf(i));
            if(i % 13 > 0 && i % 13 < 10){
                card.setValue(i % 13);
            }else{
                card.setValue(10);
            }
            if(i % 13 == 1){ // Ace的额外值为11
                card.setExValue(11);
            }
            if (i == 53 || i ==54){ //大小王额外处理
                card.setValue(0);
                card.setExValue(10);
            }
            card.setView(false);
            cardList.add(card);
        }
        Collections.shuffle(cardList);
        needClear = false; //每次洗牌都是新的一局，设置日志为不刷新
        roomLog.add("当前是第" + roomCount++ + "局");
        count = 0;
    }
    //初始化玩家卡片
    public static void initUserCard(RoomInfo roomInfo){
        Map<String, UserInfo> userInfoMap = roomInfo.getMap();
        int inGameCount = 0;
        //第一轮发牌
        for (Map.Entry<String,UserInfo> entry : userInfoMap.entrySet()) {
            UserInfo userInfo = entry.getValue();
            userInfo.setIdentity("等待要牌");//发牌后给所有闲家设置成等待要牌
            if(userInfo.getBoss()){
                userInfo.setIdentity("正在发牌");//庄家设置成正在发牌
            }
            userInfo.setUnderCard1(cardList.get(count));
            System.out.println("给" + userInfo.getUsername() + "发牌 count = " + count);
            inGameCount++;
            count++;
        }
        //第二轮发牌
        for (Map.Entry<String,UserInfo> entry : userInfoMap.entrySet()) {
            entry.getValue().setUnderCard2(cardList.get(count));
            System.out.println("给" + entry.getValue().getUsername() + "发牌 count = " + count);
            count++;
        }
        //设置游戏中人数
        roomInfo.setInGameCount(inGameCount);
        roomLog.add("系统已经给" + inGameCount + "位玩家发牌");
    }

    //清空所有用户的牌池并设置为等待中状态
    public static void clearUserCard(RoomInfo roomInfo){
        Map<String, UserInfo> userInfoMap = roomInfo.getMap();
        for (Map.Entry<String,UserInfo> entry : userInfoMap.entrySet()) {
            entry.getValue().setFrontCard1(null);
            entry.getValue().setFrontCard2(null);
            entry.getValue().setFrontCard3(null);
            entry.getValue().setUnderCard1(null);
            entry.getValue().setUnderCard2(null);
            entry.getValue().setIdentity("等待中");
        }
    }

    //给指定玩家发牌
    public synchronized static void deal(RoomInfo roomInfo,String username){
        System.out.println("给" + username + "发牌 count = " + count);
        Map<String, UserInfo> userInfoMap = roomInfo.getMap();
        UserInfo userInfo = userInfoMap.get(username);
        Card card = cardList.get(count);
        card.setView(true);//发的牌均为前置牌 均设置为可见
        if(userInfo.getFrontCard1() == null){
            userInfo.setFrontCard1(card);
            if(username.equals(roomInfo.getBossName())){
                roomLog.add("庄家给自己发了第三张牌，牌为：" + analysisCard(card));
            }else{
                roomLog.add("庄家给" + username + "发了第三张牌，牌为：" + analysisCard(card));
            }
            count++;
        }else if(userInfo.getFrontCard2() == null){
            userInfo.setFrontCard2(card);
            if(username.equals(roomInfo.getBossName())){
                roomLog.add("庄家给自己发了第四张牌，牌为：" + analysisCard(card));
            }else{
                roomLog.add("庄家给" + username + "发了第四张牌，牌为：" + analysisCard(card));
            }
            count++;
        }else if(userInfo.getFrontCard3() == null){
            userInfo.setFrontCard3(card);
            if(username.equals(roomInfo.getBossName())){
                roomLog.add("庄家给自己发了第五张牌，牌为：" + analysisCard(card));
            }else{
                roomLog.add("庄家给" + username + "发了第五张牌，牌为：" + analysisCard(card));
            }
            count++;
            Integer score = score(userInfo);
            //发满五张牌直接亮并轮换下一个要牌人
            RoomUtil.setDemandUser(roomInfo);
            if(score <= 21){
                //发出来个五小龙
                userInfo.setIdentity("五小龙!总点数" + score);
                roomLog.add("<span style:'color:red'>" + username + "达成五小龙!总点数:" + score + "</span>");
                userInfo.setCardCombo(2);
            }else{
                //炸
                roomLog.add("<span style:'color:pink'>" + username + "尝试五小龙失败!总点数:" + score + "</span>");
                userInfo.setIdentity("五小龙炸了");
            }
            userInfo.getUnderCard1().setView(true);
            userInfo.getUnderCard2().setView(true);
            roomInfo.setClearStop(username);
        }
    }


    //计算玩家手牌，返回其手牌能构成的最接近21的点数
    public static Integer score(UserInfo userInfo){
        List<Card> userCardList = new ArrayList<>();
        Card underCard1 = userInfo.getUnderCard1();
        Card underCard2 = userInfo.getUnderCard2();
        Card frontCard1 = userInfo.getFrontCard1();
        Card frontCard2 = userInfo.getFrontCard2();
        Card frontCard3 = userInfo.getFrontCard3();
        userCardList.add(underCard1);
        userCardList.add(underCard2);
        userCardList.add(frontCard1);
        userCardList.add(frontCard2);
        userCardList.add(frontCard3);
        int userPoint = 0;
        ArrayList<Integer> scoreList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {//计算5次牌值
            int small5dragon = 0;
            //这一轮卡片的值和特殊值
            Card card = userCardList.get(i);
            int value = 0;
            int exValue = -1;
            if(card != null){
                small5dragon ++;
                value = card.getValue();
                exValue = card.getExValue()!=null ? card.getExValue() : -1;
                //这一轮生成的list，用来和之前score中的list进行相加
                ArrayList<Integer> newList = new ArrayList<>();
                if(scoreList.size() == 0){
                    newList.add(value);
                    if(exValue != -1) {
                        //-1 说明是没有特殊值的牌，不添加了
                        newList.add(exValue);
                    }
                }
                for (int num :scoreList) {
                    newList.add(num + value);
                    if(exValue != -1) {
                        //-1 说明是没有特殊值的牌，不添加了
                        newList.add(num + exValue);
                    }
                }
                //将这一轮生成的和都加到scoreList中
                scoreList.addAll(newList);
                //每一轮计算的和把原来的替代掉
                scoreList = newList;
            }
        }
        Collections.sort(scoreList);
        int resultIndex = 0;
        int absoluteValue = absoluteValue(scoreList.get(resultIndex), 21);
        for (int i = 1; i < scoreList.size(); i++) {
            int temp = absoluteValue(scoreList.get(i), 21);
            if(temp < absoluteValue && scoreList.get(i) <= 21){
                resultIndex = i;
                absoluteValue = scoreList.get(i);
            }
        }
        return scoreList.get(resultIndex);
    }

    //求两个数的绝对值
    private static int absoluteValue(int a, int b){
        return a - b > 0 ? a - b : b - a;
    }

    //解析卡片的中文名称
    private static String analysisCard(Card card){
        String color = "";
        String value = "";
        if (card == null){
            return "";
        }else {
            Integer id = card.getId();
            if(id <= 13){
                color = "黑桃";
            }else if (id <= 26){
                color = "红桃";
            }else if(id <= 39){
                color = "梅花";
            }else if(id <= 52){
                color = "方块";
            }
            if(id % 13 == 0){
                value = "K";
            }else if (id % 13 <= 10){
                value = "" + (id % 13);
            }else if (id % 13 == 12){
                value = "Q";
            }else if (id % 13 == 11){
                value = "J";
            }
            if (id == 53){
                value = "小王";
            }
            if (id == 54){
                value = "大王";
            }
        }
        return color + value;
    }

}
